﻿// GameDialogMain.cpp: 实现文件
//

#include "stdafx.h"
#include "SYMFC_DLL.h"
#include "GameDialogMain.h"
#include "StringCodeAdapter.h"
#include <vector>
using namespace std;

// GameDialogMain 对话框

IMPLEMENT_DYNAMIC(GameDialogMain, CDialogEx)

GameDialogMain::GameDialogMain(CWnd* pParent /*=nullptr*/)
	: CDialogEx(IDD_DIALOG_MAIN, pParent)
	, cs_log(_T(""))
{

}

GameDialogMain::~GameDialogMain()
{
}

void GameDialogMain::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
	DDX_Text(pDX, IDC_EDIT_Log, cs_log);
}


BEGIN_MESSAGE_MAP(GameDialogMain, CDialogEx)
	ON_BN_CLICKED(IDC_BTN_GUAWU, &GameDialogMain::OnBnClickedBtnGuawu)
	ON_BN_CLICKED(IDC_BUTTON1, &GameDialogMain::OnBnClickedButton1)
	ON_BN_CLICKED(IDC_BUTTON2, &GameDialogMain::OnBnClickedButton2)
	ON_BN_CLICKED(IDC_BUTTON3, &GameDialogMain::OnBnClickedButton3)
	ON_BN_CLICKED(IDC_BUTTON4, &GameDialogMain::OnBnClickedButton4)
END_MESSAGE_MAP()


// GameDialogMain 消息处理程序

/*
可能是周围怪物链表
[[[0xF84B74] + 0x410 + 0x8]]   链表头
结点 :
+0  一个结点
+ 4
+ 4  DWORD 可能怪物ID
+ 0xC] + 0xC] + 0x8   血量  //dd [[结点+0C]+0C]+8


双向循环链表
dd[[0xF84B74] + 0x410 + 0x8]
[[[0xF84B74] + 0x410 + 0x8]]   链表头



13E1ADF0  22628BA0 + 0 下一个结点
13E1ADF4  2262B270 + 4 前一个结点


22628BA0  1359F310 + 0 下一个结点
22628BA4  13E1ADF0 + 4 前一个结点
22628BA8  FFFE5D68
22628BAC  20B58D00
22628BB0  22628BB0

//这个可能是头结点
1359F310  2262B6C0 + 0 下一个结点
1359F314  22628BA0 + 4 前一个结点
1359F318  02FAF082  game.02FAF082
1359F31C  20778E00
1359F320  1359F190



2262B6C0  226283C0 + 0 下一个结点
2262B6C4  1359F310 + 4 前一个结点
2262B6C8  FFFE5D58
2262B6CC  20B58300
2262B6D0  2262B5A0


226283C0  2262DAA0
226283C4  2262B6C0 + 4 前一个结点
226283C8  FFFE5D72


2262DAA0  2262DA00 + 0 下一个结点
2262DAA4  226283C0 + 4 前一个结点
2262DAA8  FFFE5D6B


2262DA00  22629710 + 0 下一个结点
2262DA04  2262DAA0 + 4 前一个结点
2262DA08  FFFEC083

22629710  2262B270 + 0 下一个结点
22629714  2262DA00 + 4 前一个结点
22629718  FFFE5D69
2262971C  20B57400



2262B270  13E1ADF0 + 0 下一个结点
2262B274  22629710 + 4 前一个结点

*/
DWORD R4(UINT_PTR address) {
	__try {
		return *(DWORD*)address;
	}
	__except (1) {
		return 0;
	}
}
UINT_PTR getChainHead() {
	return R4(R4(0xF84B74) + 0x410 + 0x8);
}
void printLinkedList(UINT_PTR  linkedNode, CString &cs_log) {
	UINT_PTR nextChain = R4(linkedNode + 0);
	UINT_PTR prevChain = R4(linkedNode + 4);
	DWORD monsterObj = R4(R4(linkedNode + 0xC) + 0xC);
	if (monsterObj!=NULL) {
		//怪物的血量
		DWORD monsterBlood = (monsterObj + 8);
		DWORD   nameAddress = (monsterObj + 0x100);
		DWORD   flagAddress = (monsterObj + 0x114);
		//cmp     dword ptr[edi + 114], 10
		TRACE("wx:linkedNode=%x,monsterObj=%x\r\n", linkedNode, monsterObj);
		//TRACE("wx:nameAddress=%x,monsterBlood=%x,flagAddress=%x", nameAddress, monsterBlood, flagAddress);
		TRACE("wx:%x=nameAddress=%s,monsterBlood=%d,flagAddress=%x", nameAddress,BIG5ToGB2312((char*)nameAddress) , *(DWORD*)monsterBlood, *(DWORD*)flagAddress);
		CString line;
		line.Format(_T("wx:附近对象的地址=%x,名称%s,,血量=%d\r\n"), monsterObj, BIG5ToGB2312((char*)nameAddress), *(DWORD*)monsterBlood);
		cs_log += line;
	}

	/*DWORD   addressR4 = R4(R4(R4(linkedNode + 0xC) + 0xC) + 0x100);
	TRACE("wx:address=%x,addressR4=%x\r\n", address, addressR4);
	char* monsterName1 = (char*)address;
	char* monsterName2 = (char*)addressR4;
	CString line;
	line.Format(_T("wx:附近对象的地址=%x,名称%s,%s,血量=%d\r\n"), linkedNode, BIG5ToGB2312(monsterName1), BIG5ToGB2312(monsterName2), monsterBlood);
	cs_log += line;*/
	
}
void eachLinkedChain(CString &cs_log) {
	//链表入口
	//UINT_PTR  chainHead = getChainHead();
	////链表下一个节点
	//UINT_PTR nextChain = R4(chainHead + 0);
	////链表上一个节点
	//UINT_PTR prevChain = R4(chainHead + 4);
	TRACE("wx:eachLinkedChain()");
	//链表入口
	UINT_PTR  nodeHead = getChainHead();
	UINT_PTR  nextNode = nodeHead;
	while (TRUE) {
		nextNode = R4(nextNode + 0);
		printLinkedList(nextNode, cs_log);
		if (nextNode == nodeHead) {
			break;
		}

	}
}
void GameDialogMain::OnBnClickedBtnGuawu()
{
	// TODO: 在此添加控件通知处理程序代码
	TRACE("wx:点击遍历CALL");
	cs_log.Empty();
	eachLinkedChain(cs_log);
	this->UpdateData(FALSE);
	cs_log.ReleaseBuffer();
}
   

DWORD  getGamePlayer() {
	DWORD gamePlayer = NULL;
	__asm {
		mov eax, 0x006DA210
		call  eax
		mov gamePlayer,eax
	}
	return gamePlayer;
}
DWORD getGoodsName(DWORD id) {
	DWORD nameAddress = NULL;
	__asm {
		mov     edx, id
		mov     ecx, 0x1789168
		mov     ecx,[ecx]
		mov     eax,[ecx]
		push    edx
		mov     edx, dword ptr[eax + 0xA8]
		call    edx
		mov nameAddress,eax
	}
	return nameAddress;
}


void nodeF4(DWORD node, DWORD snode , vector<DWORD>* nodeList) {
	TRACE("wx:node=%x,snode=%x", node, snode);
	BYTE  flag = (BYTE)R4(node + 0x15);//判断是否进入
	TRACE("wx:node=%x,flag=%x", node, flag);
	if (flag ==0) {
		if (R4(node) != snode) {
			DWORD nnode = R4(node);
			TRACE("wx:nnode=%x", nnode);
			nodeList->push_back(nnode);
			nodeF4(nnode, snode, nodeList);
		}
		if (R4(node + 8) != snode) {
			DWORD nnode = R4(node + 8);
			TRACE("wx:nnode=%x", nnode);
			nodeList->push_back(nnode);
			nodeF4(nnode, snode, nodeList);
		}
	}
}
void eachBackList(CString &cs_log) {

	DWORD gamePlayer = getGamePlayer();
	TRACE("wx:gamePlayer=%x", gamePlayer);
	DWORD snode =      R4(R4(gamePlayer + 0x3C0) + 0x4);//判断是否进入
	DWORD node = R4( snode+4);
	vector<DWORD> nodeList ;
	nodeList.push_back(node);
	nodeF4(node, snode, &nodeList);
	TRACE("wx:nodeList=%d", nodeList.size());
	for (DWORD i = 0; i < nodeList.size();i++) {
		DWORD newNode = nodeList[i];
		TRACE("wx:newNode=%x", newNode);

		/*TRACE("wx: R4(node + 0)=%x", nnode);
	TRACE("wx: R4(nnode+0x10)=%x", R4(nnode + 0x10));
	TRACE("wx: R4(R4(nnode + 0x10) + 0x8)=%x", R4(R4(nnode + 0x10) + 0x8));
	TRACE("wx: R4(R4(nnode + 0x10) + 0x8)=%x", R4(R4(nnode + 0x10) + 0xC));*/
	DWORD length = (R4(R4(newNode + 0x10) + 0xC) - R4(R4(newNode + 0x10) + 0x8)) / 4;
	DWORD startObj = *(DWORD*)(R4(newNode + 0x10) + 0x8);
	/*TRACE("wx:startObj=%x", startObj);
	TRACE("wx:length=%x", length);*/
	for (DWORD i = 0; i < length; i++) {
		DWORD goodsObj = R4(startObj + i * 4);
		TRACE("wx:goodsObji=%x", goodsObj);
		if ((*(WORD*)goodsObj) == 0) {
			TRACE(_T("wx:第%d,格的物品为空\r\n"), i);
			CString line;
			line.Format(_T("wx:第%d,格的物品为空\r\n"), i);
			cs_log += line;
		}
		else {
			WORD goodsNum = *(WORD*)(goodsObj + 0x28);
			DWORD goodsId = (*(WORD*)goodsObj);

			DWORD nameAddress = getGoodsName(goodsId);
			//TRACE(_T("wx:第%d,格的名称的地址%x\r\n"), i, nameAddress);
			DWORD nameAddress2 = (nameAddress + 0xF8 + 0x4);
			DWORD nameAddress3 = (nameAddress2 + 0x10);
			TRACE(_T("wx:第%d,nameAddress2=%x"), i, nameAddress2);
			TRACE(_T("wx:第%d,nameAddress3=%x"), i, nameAddress3);
			DWORD flag = *(DWORD*)(nameAddress3);
			TRACE(_T("wx:第%d,格的物品名称flag=%x"),i,flag);
			char* name = "";
			if (flag==0x10) {
				 nameAddress2 = *(DWORD*)nameAddress2;
				 TRACE(_T("wx:第%d,格的物品名称nameAddress2=%x"), i, nameAddress2);
				 name = (char*)nameAddress2;
			}
			else {
				name = (char*)nameAddress2;
			}
			
			//TRACE(_T("wx:第%d,格的物品对象=%x，物品ID=%x,物品数量=%d 物品名称%s\r\n"), i, goodsObj, goodsId, goodsNum, BIG5ToGB2312(name));
			CString line;
			line.Format(_T("wx:第%d,物品对象=%x,格的物品ID=%x,物品数量=%d 物品名称地址%x,物品名称%s\r\n"), i, goodsObj, goodsId, goodsNum, nameAddress2, BIG5ToGB2312(name));
			cs_log += line;
			/*TRACE(_T("wx:第%d,格的名称的地址+ 0xF8 + 0x4 =%x\r\n"), i,  nameAddress2);
			TRACE(_T("wx:第%d,没转换的name =%s,%x\r\n"), i, name, name);
			TRACE(_T("wx:第%d,转换后的name =%s\r\n"), i, BIG5ToGB2312(name));*/
		}
	}
		
	
	
	}
	

}
void GameDialogMain::OnBnClickedButton1()
{
	// 遍历封包
	cs_log.Empty();
	eachBackList(cs_log);
	this->UpdateData(FALSE);
	cs_log.ReleaseBuffer();
}

//裸函数

__declspec(naked) void 加密call(DWORD 秘钥, DWORD 加密长度, DWORD 加密地址, DWORD 加密地址2) {
	__asm {
		push    ebp
		push    ebx
		push    esi
		push    edi
		mov     edi, dword ptr[esp + 0x14]
		mov     edx, dword ptr[esp + 0x18]
		mov     esi, dword ptr[esp + 0x1C]
		mov     ebp, dword ptr[esp + 0x20]
		xor eax, eax
		xor     ebx, ebx
		cmp     edx, 0x0
		je      Lable1
		mov     al, byte ptr[edi]
		mov     bl, byte ptr[edi + 0x4]
		add     edi, 0x8
		lea     ecx, dword ptr[esi + edx]
		sub     ebp, esi
		mov     dword ptr[esp + 0x18], ecx
		inc     al
		cmp     dword ptr[edi + 0x100], -1
		je      Lable2
		mov     ecx, dword ptr[edi + eax * 0x4]
		and edx, 0xFFFFFFFC
		je      Lable3
		lea     edx, dword ptr[esi + edx - 0x4]
		mov     dword ptr[esp + 0x1C], edx
		mov     dword ptr[esp + 0x20], ebp
		nop
		nop
		nop
		nop
		nop
		nop
		Lable4 :
		add     bl, cl
			mov     edx, dword ptr[edi + ebx * 0x4]
			mov     dword ptr[edi + ebx * 0x4], ecx
			mov     dword ptr[edi + eax * 0x4], edx
			add     edx, ecx
			inc     al
			and     edx, 0x0FF
			mov     ecx, dword ptr[edi + eax * 0x4]
			mov     ebp, dword ptr[edi + edx * 0x4]
			add     bl, cl
			mov     edx, dword ptr[edi + ebx * 0x4]
			mov     dword ptr[edi + ebx * 0x4], ecx
			mov     dword ptr[edi + eax * 0x4], edx
			add     edx, ecx
			inc     al
			and     edx, 0x0FF
			ror     ebp, 0x8
			mov     ecx, dword ptr[edi + eax * 0x4]
			or ebp, dword ptr[edi + edx * 0x4]
			add     bl, cl
			mov     edx, dword ptr[edi + ebx * 0x4]
			mov     dword ptr[edi + ebx * 0x4], ecx
			mov     dword ptr[edi + eax * 0x4], edx
			add     edx, ecx
			inc     al
			and     edx, 0x0FF
			ror     ebp, 0x8
			mov     ecx, dword ptr[edi + eax * 0x4]
			or ebp, dword ptr[edi + edx * 0x4]
			add     bl, cl
			mov     edx, dword ptr[edi + ebx * 0x4]
			mov     dword ptr[edi + ebx * 0x4], ecx
			mov     dword ptr[edi + eax * 0x4], edx
			add     edx, ecx
			inc     al
			and     edx, 0x0FF
			ror     ebp, 0x8
			mov     ecx, dword ptr[esp + 0x20]
			or ebp, dword ptr[edi + edx * 0x4]
			ror     ebp, 0x8
			xor ebp, dword ptr[esi]
			cmp     esi, dword ptr[esp + 0x1C]
			mov     dword ptr[ecx + esi], ebp
			lea     esi, dword ptr[esi + 0x4]
			mov     ecx, dword ptr[edi + eax * 0x4]
			jb      Lable4
			cmp     esi, dword ptr[esp + 0x18]
			je      Lable5
			mov     ebp, dword ptr[esp + 0x20]
			nop
			nop
			nop
			Lable3 :
		add     bl, cl
			mov     edx, dword ptr[edi + ebx * 0x4]
			mov     dword ptr[edi + ebx * 0x4], ecx
			mov     dword ptr[edi + eax * 0x4], edx
			add     edx, ecx
			inc     al
			and     edx, 0x0FF
			mov     edx, dword ptr[edi + edx * 0x4]
			xor dl, byte ptr[esi]
			lea     esi, dword ptr[esi + 0x1]
			mov     ecx, dword ptr[edi + eax * 0x4]
			cmp     esi, dword ptr[esp + 0x18]
			mov     byte ptr[ebp + esi - 0x1], dl
			jb      Lable3
			jmp     Lable5
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			nop
			Lable2 :
		movzx   ecx, byte ptr[edi + eax]
			Lable6 :
			add     bl, cl
			movzx   edx, byte ptr[edi + ebx]
			mov     byte ptr[edi + ebx], cl
			mov     byte ptr[edi + eax], dl
			add     dl, cl
			movzx   edx, byte ptr[edi + edx]
			add     al, 1
			xor dl, byte ptr[esi]
			lea     esi, dword ptr[esi + 1]
			movzx   ecx, byte ptr[edi + eax]
			cmp     esi, dword ptr[esp + 0x18]
			mov     byte ptr[ebp + esi - 0x1], dl
			jb      Lable6
			Lable5 :
		dec     al
			mov     byte ptr[edi - 0x4], bl
			mov     byte ptr[edi - 0x8], al
			Lable1 :
		pop     edi
			pop     esi
			pop     ebx
			pop     ebp
			retn
			nop
	}
}


void GameDialogMain::OnBnClickedButton2()
{
	byte 喊话内容封包[100] = { 0x12 ,0x00 ,0x7E ,0x00 ,0x00 ,0x00 ,0x00 ,0x03 ,0x00 ,0x31 ,0x31 ,0x30 ,0xFF ,0xFF ,0xFF ,0xFF ,0x00 ,0x00 ,0x00 ,0x00};
	// 喊话发包
	DWORD 秘钥 = NULL;
	__asm {
		mov ecx, 0xF84BA4
		mov ecx,[ecx]
		mov ecx, [ecx]
		mov ecx, [ecx+0x4]
		mov ecx, [ecx+0x14]
		mov ecx, [ecx]
		lea ecx, [ecx+0x54]
		mov 秘钥,ecx
	}
	DWORD 包长 = 0x14;
	DWORD 包地址 = (DWORD)喊话内容封包;
	DWORD  加密长度 = 包长 - 2;
	DWORD 加密地址 = 包地址 + 2;
	
	加密call(秘钥, 加密长度, 加密地址, 加密地址);
	
	HWND 窗口句柄 = ::FindWindowA("Lapis Network Class",0);
	DWORD a = GetWindowLongW(窗口句柄,-21);
	DWORD s = *(DWORD*)(a+0x38);
	send(s, (const char*)包地址, 包长, 0);
}


void GameDialogMain::OnCancel()
{
	// TODO: 在此添加专用代码和/或调用基类
	
	CDialogEx::OnCancel();
}


void GameDialogMain::OnBnClickedButton3()
{
	// TODO: 在此添加控件通知处理程序代码
	   /* 0084CC10    55              push    ebp
		0084CC11    8BEC            mov     ebp, esp
		0084CC13    8B51 04         mov     edx, dword ptr[ecx + 4]
		0084CC16    8B42 04         mov     eax, dword ptr[edx + 4]
		0084CC19    83EC 10         sub     esp, 10
		0084CC1C    8078 15 00      cmp     byte ptr[eax + 15], 0
		0084CC20    56              push    esi
		0084CC21    57              push    edi
		0084CC22    8B7D 0C         mov     edi, dword ptr[ebp + C]
		0084CC25    75 1D           jnz     short 0084CC44
		0084CC27    8B37            mov     esi, dword ptr[edi]
		0084CC29    8DA424 00000000 lea     esp, dword ptr[esp]
		0084CC30    3970 0C         cmp     dword ptr[eax + C], esi
		0084CC33    7D 05           jge     short 0084CC3A
		0084CC35    8B40 08         mov     eax, dword ptr[eax + 8]
		0084CC38    EB 04           jmp     short 0084CC3E
		0084CC3A    8BD0            mov     edx, eax
		0084CC3C    8B00            mov     eax, dword ptr[eax]
		0084CC3E    8078 15 00      cmp     byte ptr[eax + 15], 0; 标准二叉树遍历*/
	    //根节点  dd  [[[[17EA2B0] + 30] + 4 + 4] + 4]

	cs_log.Empty();
	vector<DWORD> nodeList;
	DWORD snode = R4(R4(R4(0x17EA2B0) + 0x30) + 0x8);//判断是否进入
	DWORD node = R4(snode + 4);
	nodeList.push_back(node);
	nodeF4(node, snode,&nodeList);
	TRACE("wx:nodeList=%d", nodeList.size());
	for (DWORD i = 0; i < nodeList.size(); i++) {
		DWORD newNode = nodeList[i];
		DWORD id = *(DWORD*)(newNode + 0xC);
		DWORD timeAddress = R4(newNode + 0x10);
		TRACE("wx:timeAddress=%x\r\n", timeAddress);
		float time = *(float*)(timeAddress + 0x10);
		CString line;
		line.Format(_T("冷却中的技能id=%x，冷却时间%f \r\n"),id, time);
		cs_log += line;
	}
	this->UpdateData(FALSE);
}

DWORD  getSkillName(DWORD id) {

	DWORD skillNameAddress = NULL;
	__asm {
		mov     ecx, 0x1789168
		mov     ecx,[ecx]
		mov     edx, dword ptr[ecx]
		mov     edx, dword ptr[edx + 0xC4]
		push    id
		call    edx
		mov skillNameAddress,eax
	}
	return skillNameAddress;
}
DWORD getGamePlayerSkill() {
	DWORD gamePlayer = NULL;
	__asm {
			mov eax,0x006DA280
		    call     eax
			mov gamePlayer,eax
	}
	return gamePlayer;
}
void GameDialogMain::OnBnClickedButton4()
{
	// TODO: 在此添加控件通知处理程序代码
	   /* 008EFF2E    8B0D 68917801   mov     ecx, dword ptr[1789168]
		008EFF34    8B11            mov     edx, dword ptr[ecx]
		008EFF36    8B45 10         mov     eax, dword ptr[ebp + 10]
		008EFF39    8B92 C4000000   mov     edx, dword ptr[edx + C4]
		008EFF3F    50              push    eax
		008EFF40    89B5 3CFFFFFF   mov     dword ptr[ebp - C4], esi
		008EFF46    FFD2            call    edx*/
	//getSkillName()+104

	   /* 008F0104    E8 77A1DEFF     call    006DA280
		008F0109    56              push    esi
		008F010A    50              push    eax; [[[eax + c] + 444 + 4] + 4]
		008F010B    B9 2875F800     mov     ecx, 00F87528
		008F0110    8945 D4         mov     dword ptr[ebp - 2C], eax*/

	   /* 006DA210    8B0D 744BF800   mov     ecx, dword ptr[F84B74]; [F84B74] + 0x410
		006DA216    85C9            test    ecx, ecx
		006DA218    75 0B           jnz     short 006DA225
		006DA21A    E8 A165F8FF     call    006607C0
		006DA21F    8B0D 744BF800   mov     ecx, dword ptr[F84B74]
		006DA225    8B81 0C040000   mov     eax, dword ptr[ecx + 40C]
		006DA22B    85C0            test    eax, eax
		006DA22D    7C 10           jl      short 006DA23F
		006DA22F    50              push    eax
		006DA230    81C1 10040000   add     ecx, 410; ecx + 410
		006DA236    E8 35B6F8FF     call    00665870; ====
		006DA23B    85C0            test    eax, eax
		006DA23D    75 05           jnz     short 006DA244
		006DA23F    A1 CC73F800     mov     eax, dword ptr[F873CC]
		006DA244    8B40 0C         mov     eax, dword ptr[eax + C]; [eax + 0xC]
		006DA247    C3              retn*/
	cs_log.Empty();
	DWORD gamePlayerSkill = getGamePlayerSkill();
	DWORD gamePlayer = getGamePlayer();
	TRACE("wx:gamePlayerSkill=%x,gamePlayer=%x\r\n", gamePlayerSkill, gamePlayer);
	vector<DWORD> nodeList;
	DWORD snode = R4(R4(gamePlayerSkill + 0xC) + 0x448);//[[[eax + c] + 444 + 4] + 4]
	DWORD node = R4(snode + 4);
	//TRACE("wx:snode=%x,node=%x,\r\n", snode, node);
	nodeList.push_back(node);
	nodeF4(node, snode, &nodeList);
	TRACE("wx:nodeList=%d\r\n", nodeList.size());
	for (DWORD i = 0; i < nodeList.size(); i++) {
		DWORD newNode = nodeList[i];
		DWORD idAdress = (newNode+0xC);
		WORD  skillId = *(WORD*)idAdress;
		DWORD nameAddress = getSkillName(skillId);
		char*  skillName = (char*)(nameAddress + 0x104);
		
		TRACE("wx:newNode=%x,idAdress=%x,id=%x,nameAddress=%x", newNode, idAdress,*(WORD*)idAdress, nameAddress);
		CString line;
		line.Format(_T("技能对象=%x，技能ID=%x,技能名称=%s\r\n"), newNode, skillId, BIG5ToGB2312(skillName));
		cs_log += line;
	}

	this->UpdateData(FALSE);

}
